//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.eResearch.Common.Threading
{
    using System;
    using System.Threading;

    /// <summary>
    /// Represents an acquired reader lock using <see cref="ReaderWriterLockSlim"/>.
    /// </summary>
    public class AcquireReaderLock : IDisposable
    {
        /// <summary>
        /// Instance of read write lock.
        /// </summary>
        private ReaderWriterLockSlim slimLock = null;

        /// <summary>
        /// Field to help Dispose method.
        /// </summary>
        private bool disposed;

        /// <summary>
        /// Initializes a new instance of the <see cref="AcquireReaderLock"/> class.
        /// </summary>
        /// <param name="slimLock">The read write lock.</param>
        public AcquireReaderLock(ReaderWriterLockSlim slimLock)
        {
            this.slimLock = slimLock;
            this.slimLock.EnterReadLock();
        } 

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, 
        /// or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources.
        /// </summary>
        /// <param name="disposing">Pass <c>true</c> to release both managed and 
        /// unmanaged resources; <c>false</c> to release only unmanaged resources.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    slimLock.ExitReadLock();
                }
            }

            disposed = true;
        } 
    }
}
